/**
    ******************************************************************************
    * @file    queue.c
    * @author  debian
    * @version V1.0.0
    * @date    2019-12-01
    * @brief   队列
    ******************************************************************************
    * @attention
    *
    *
    ******************************************************************************
    */ 

/* Includes ------------------------------------------------------------------*/
#include "queue.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>


/** @addtogroup DataStruct_Driver
    * @{
    */

/** @addtogroup queue
    * @{
    */

/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

/* Private function prototypes -----------------------------------------------*/

/* Private functions ---------------------------------------------------------*/


/** @defgroup queue_Exported_Functions queue Exported Functions
    * @{
    */

/** @defgroup queue_Exported_Functions_Group1 Initialization and deinitialization functions
    *  @brief    Initialization and Configuration functions
    *
@verbatim    
    ===============================================================================
                ##### Initialization and deinitialization functions #####
    ===============================================================================
    [..]
        This section provides functions allowing to initialize and de-initialize the queue
        to be ready for use.
 
@endverbatim
    * @{
    */ 

/**
    * @brief  创建queue对象
    * @param  
    * @retval 
    */ 
    int queue_creat(struct Queue *q, int size)
    {
		assert(q);

		q->data = (Elemtype *)calloc(size, sizeof(Elemtype));
		assert(q->data);

		q->size = size;
		q->rear = q->front = 0;

		return 0;
    }

/**
    * @brief  销毁queue对象
    * @param  
    * @retval 
    */ 
    int queue_destroy(struct Queue *q)
    {
		assert(q);

		if(q->data)
			free(q->data);
		
		return 0;
    }
    
/**
    * @}
    */

/** @defgroup queue_Exported_Functions_Group2 operation functions 
    *  @brief   operation functions
    *
@verbatim   
    ===============================================================================
                        ##### operation functions #####
    ===============================================================================
    [..]
        This subsection provides a set of functions allowing to manage the queue.

@endverbatim
    * @{
    */

        /* 操作函数写在这里 */
/**
	* @brief  入队
	* @param  
	* @retval 
	*/ 
	int queue_enter(struct Queue *q, Elemtype data)
	{
		assert(q);

		//判断队列是否满
		if((q->rear+1)%q->size == q->front)
		{
			//扩容
			int new_len = (q->size>>1)+q->size;
			q->data = realloc(q->data, sizeof(Elemtype)*new_len);
			assert(q->data);

			if(q->rear < q->front)
			{
				int i;
				int old_len = q->size;
				for(i=0; i<q->rear; i++)
				{
					q->data[old_len++] = q->data[i]; 
				}
				q->rear = old_len;
			}

			q->size = new_len;
		}
			
		q->data[q->rear] = data;
		q->rear = (q->rear+1)%q->size;
		
		return 0;
	}


/**
	* @brief  出队
	* @param  
	* @retval 
	*/ 
	int queue_delete(struct Queue *q, Elemtype *data)
	{
		assert(q);
		assert(data);

		//判断队列是否为空
		if(q->rear == q->front)
			return -1;

		*data = q->data[q->front];
		q->front = (q->front+1)%q->size;
		
		return 0;
	}



	/**
		* @brief  遍历栈
		* @param  
		* @retval 
		*/ 
		int queue_traversal(struct Queue *q)
		{
			if(q == NULL)
				return -1;
	
			int i = 0;
			int head = (q->front)%q->size;
			int tail = (q->rear)%q->size;
			printf("traversal %d %d\n", head, tail);
			for(i=head; i != tail; i=(i+1)%q->size)   //这样遍历
			{		
				printf("%d ", q->data[i]);
			}
			printf("\n");
			
			return 0;
		}
	
	
	
	#if 1
		int main()
		{
			int i = 0;
			int ret = -1;
	
			struct Queue s;
			int a = -1;
			
			queue_creat(&s, 4);
	
			queue_enter(&s, 2);
			queue_enter(&s, 5);
			queue_enter(&s, 6);
			queue_traversal(&s);
			queue_enter(&s, 9);
			queue_traversal(&s);
			
			queue_enter(&s, 7);

			queue_traversal(&s);

			queue_delete(&s, &a);
			queue_delete(&s, &a);

			queue_traversal(&s);
			
			queue_enter(&s, 9);
			queue_enter(&s, 11);
			queue_traversal(&s);
			queue_enter(&s, 17);
	
			queue_traversal(&s);
	
			//queue_delete(&s, &a);
			//printf("aaa = %d\n", a);
			//queue_bainli(&s);
			
			return 0;
	
		}
	#endif


    /**
    * @}
    */


/**
    * @}
    */

/**
    * @}
    */

/**
    * @}
    */

/************************ (C) 2019 HOME 深圳龙华 *****END OF FILE****/

